//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include "ddk.h"
//#include "elapi.h"
#ifndef _win32
#include "stub.h"
#endif
//#include "eltypes.h"
#include "CBasicFileSystem.h"
#include "FileSystemControl.h"

extern IDeviceDriver * CDECL CreateBlkFlash(uint_t uDeviceNo, void *pvParameter);

class ktfsdev : public CDeviceDriver
{
public:
    CARAPI Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 uNumberOfBytesToRead,
        /* [out] */ MemoryBuf * pData,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ const MemoryBuf & ebbData,
        /* [out] */ Int32 * puNumberOfBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ const MemoryBuf & ebbInData,
        /* [out] */ MemoryBuf * pOutData,
        /* [out] */ IEvent * * ppCompletionEvent);
    virtual ~ktfsdev();
    virtual void Dispose();
};

CARAPI ktfsdev::Read(
    /* [in] */ Int64 u64Offset,
    /* [in] */ Int32 uNumberOfBytesToRead,
    /* [out] */ MemoryBuf * pData,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return NOERROR;
}

CARAPI ktfsdev::Write(
    /* [in] */ Int64 u64Offset,
    /* [in] */ const MemoryBuf & ebbData,
    /* [out] */ Int32 * puNumberOfBytesWritten,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return NOERROR;
}

CARAPI ktfsdev::Control(
    /* [in] */ Handle32 nControlCode,
    /* [in] */ const MemoryBuf & ebbInData,
    /* [out] */ MemoryBuf * pOutData,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    wchar_t *serviceName = NULL;
    IBasicFileSystem *pIBFS = NULL;
    ECode ec;
    IStub *pStub = NULL;

    if (!ebbInData.GetCapacity()) {
        return E_INVALID_ARGUMENT;
    }
    serviceName = (wchar_t *)ebbInData.GetPayload();
    assert(wcslen(serviceName) > 0);

    switch (nControlCode) {
        case FILESYSTEM_CONTROL_CREATE:
            pIBFS = new CKtfsFileSystem();
            if (NULL == pIBFS) {
                return E_OUT_OF_MEMORY;
            }
            pIBFS->AddRef();

            ec = DzRegisterService(serviceName, pIBFS, &pStub);
            if (ec != NOERROR) {
                pIBFS->Release();
                return ec;
            }
            assert(pStub != NULL);
            ((CKtfsFileSystem*)pIBFS)->SetStub(pStub);
            pIBFS->Release();

            break;

        case FILESYSTEM_CONTROL_DELETE:
            ec = DzFindService(serviceName, (PInterface *)&pIBFS);
            if (ec != NOERROR) {
                return ec;
            }

            pStub = ((CKtfsFileSystem*)pIBFS)->GetStub();
            assert(pStub != NULL);

            ec = DzUnregisterService(serviceName, pStub);
            if (ec != NOERROR) {
                return ec;
            }

            pIBFS->Release();
            break;

        default:
            break;
    }
    return NOERROR;
}

ktfsdev::~ktfsdev()
{
    this->Release();
}

void ktfsdev::Dispose()
{
    delete this;
}

EXTERN IDeviceDriver* CDECL CreateKtfs(uint_t uDeviceNo, void *pvParameter)
{
    ktfsdev *pKtfsDriver = new ktfsdev();
    if (NULL == pKtfsDriver) {
        return NULL;
    }
    pKtfsDriver->AddRef();
    return pKtfsDriver;
}
